package com.sky.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.context.BaseContext;
import com.sky.dto.BatchUpdateRequest;
import com.sky.dto.PageQuery;
import com.sky.dto.ReviewDTO;
import com.sky.entity.Book;
import com.sky.entity.Review;
import com.sky.entity.User;
import com.sky.entity.UserActionLog;
import com.sky.mapper.UserMapper;
import com.sky.repository.BookRepository;
import com.sky.repository.ReviewRepository;
import com.sky.repository.UserActionLogRepository;
import com.sky.result.PageResult;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ReviewServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(ReviewServiceImpl.class);
    private final ReviewRepository reviewRepository;
    private final BookRepository bookRepository;
    private final UserMapper userMapper;
    private final UserActionLogRepository logRepository;

    @Autowired
    public ReviewServiceImpl(ReviewRepository reviewRepository,
                             BookRepository bookRepository,
                             UserMapper userMapper,UserActionLogRepository logRepository) {
        this.reviewRepository = reviewRepository;
        this.bookRepository = bookRepository;
        this.userMapper = userMapper;
        this.logRepository = logRepository;
    }

    //    添加书评
    public void add(ReviewDTO reviewDTO) {
        Review review = new Review();
        // 作者id
        review.setUId(BaseContext.getCurrentId());
        // 设置为待审核状态
        review.setStatus(Review.PENDING);
        // 设置修改时间
        review.setUpdateTime(reviewDTO.getCreateTime());
        // 拷贝属性
        BeanUtils.copyProperties(reviewDTO, review);
        // 存入数据库
        reviewRepository.save(review);
        // 记录操作日志
        UserActionLog log = new UserActionLog();
        log.setAction("review");
        log.setBId(review.getBId());
        log.setTimestamp(new Date());
        // 假设通过安全上下文获取当前用户
        log.setUId(BaseContext.getCurrentId());
        log.setScore(reviewDTO.getRating());
        logRepository.save(log);
        logger.info("Review was added: {}", reviewDTO);
    }

    //获取书评详情
    public ReviewResult getReviewResult(String id) {
        Review review = reviewRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Review not found with id: " + id));

        ReviewVO reviewVO = convertToReviewVO(review);
        UserInfoVO userInfo = getUserInfo();

        return ReviewResult.builder()
                .review(reviewVO)
                .userInfo(userInfo)
                .build();
    }

    /**
     * 分页查询已发布的书评
     *
     * @return
     */
    public PageResult list(PageQuery pageQuery) {
        Page<Review> page;
        if (pageQuery.getStatus() == null) {
            page = reviewRepository.findAll(
                    PageRequest.of(pageQuery.getPage() - 1, pageQuery.getSize(),
                            Sort.by(Sort.Direction.DESC, "createTime"))
            );
        } else {
            page = reviewRepository.findByStatus(
                    pageQuery.getStatus(),
                    PageRequest.of(pageQuery.getPage() - 1, pageQuery.getSize(),
                            Sort.by(Sort.Direction.DESC, "createTime"))
            );
        }
        List<ReviewVO> record = page.getContent().stream()
                .map(this::convertToReviewVO)
                .collect(Collectors.toList());
        return new PageResult(page.getTotalElements(), record);
    }

    private UserInfoVO getUserInfo() {
        Integer uId = BaseContext.getCurrentId();
        User user = userMapper.getById(uId);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        return userInfoVO;
    }

    private ReviewVO convertToReviewVO(Review review) {
        if (review == null) return null;

        ReviewVO reviewVO = new ReviewVO();
        BeanUtils.copyProperties(review, reviewVO);

        // 设置默认统计值（考虑从数据库获取真实数据）
        reviewVO.setLikeCount(256);
        reviewVO.setCommentCount(25);
        reviewVO.setShareCount(72);
        reviewVO.setCollectCount(15);

        // 设置作者信息
        User author = userMapper.getById(review.getUId());
        reviewVO.setAuthor(convertToAuthorVO(author));

        // 设置书籍信息
        Book book = bookRepository.findById(review.getBId()).orElse(null);
        reviewVO.setBook(convertToBookVO(book));

        return reviewVO;
    }

    private AuthorVO convertToAuthorVO(User user) {
        if (user == null) return null;
        AuthorVO authorVO = new AuthorVO();
        BeanUtils.copyProperties(user, authorVO);
        return authorVO;
    }

    private BookVO convertToBookVO(Book book) {
        if (book == null) return null;
        BookVO bookVO = new BookVO();
        BeanUtils.copyProperties(book, bookVO);
        return bookVO;
    }

    /**
     * 修改书评状态
     * @param id
     * @param status
     */
    public void update(String id, Integer status) {
        Review review = reviewRepository.findById(id).orElse(null);
        review.setStatus(status);
        review.setUpdateTime(new Date());
        reviewRepository.save(review);
    }

    /**
     * 批量修改书评状态
     * @param request
     */
    @Transactional
    public void batchUpdateStatus(BatchUpdateRequest request) {
        int batchSize = 100; // 每批处理100条
        List<String> ids = request.getIds();
        Integer status = request.getStatus();
        for (int i = 0; i < ids.size(); i += batchSize) {
            List<String> batchIds = ids.subList(i, Math.min(i + batchSize, ids.size()));
            // 1. 查询出这批记录
            List<Review> reviews = (List<Review>) reviewRepository.findAllById(batchIds);

            // 2. 批量更新状态和更新时间
            reviews.forEach(review -> {
                review.setStatus(request.getStatus());
                review.setUpdateTime(new Date());  // 设置更新时间
            });

            // 3. 批量保存
            reviewRepository.saveAll(reviews);
        }
    }

}